home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / go32 / fs / ed.c < prev    next >
C/C++ Source or Header  |  1995-03-23  |  9KB  |  325 lines

  1. #include <std.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <setjmp.h>
  5. #include <go32.h>
  6. #define far
  7.  
  8. #include "ed.h"
  9. #include "paging.h"
  10. #include "unassmbl.h"
  11. #include "debug.h"
  12. #include "syms.h"
  13. /*
  14. void movedata(int srcseg, int srcofs, int destseg, int destofs, int length);
  15. */
  16. ExternalDebuggerInfo edi;
  17. TSS a_tss;
  18. AREAS areas[MAX_AREA];
  19. int old_go32, remote;
  20. char *sympath, *symname, *symext, *startup_file;
  21. word32 dos_mem_lo, dos_mem_hi;
  22.  
  23. static TSS org_tss;
  24. static int my_ds;
  25. static int app_ds;
  26. static int edi_seg;
  27. static int edi_ofs;
  28. /* -------------------------------------------------------------- */
  29. static void
  30. edi_init (void)
  31. {
  32.   int i;
  33.   asm("movw $0xfe01,%ax");
  34.   asm("int $0x21");
  35.   asm("movl %edx,_edi_seg");
  36.   asm("movl %eax,_edi_ofs");
  37.   asm("xor  %eax,%eax");
  38.   asm("movw %ds,%ax");
  39.   asm("movl %eax,_my_ds");
  40.   movedata(edi_seg, edi_ofs, my_ds, (int)(&edi), sizeof(edi));
  41.   movedata(edi.a_tss_seg, edi.a_tss_ofs, my_ds, (int)(&a_tss), sizeof(TSS));
  42.   memcpy (&org_tss, &a_tss, sizeof (TSS));
  43.   app_ds = a_tss.tss_ds;
  44.   movedata(edi.areas_seg, edi.areas_ofs, my_ds, (int)areas, sizeof(areas));
  45.   for (i=0; i<MAX_AREA; i++)
  46.   {
  47.     areas[i].first_addr -= edi.app_base;
  48.     areas[i].last_addr -= edi.app_base;
  49.   }
  50. }
  51. /* -------------------------------------------------------------- */
  52. void run_child(void)
  53. {
  54.   int i;
  55.   movedata(my_ds, (int)(&edi), edi_seg, edi_ofs, sizeof(edi));
  56.   movedata(my_ds, (int)(&a_tss), edi.a_tss_seg, edi.a_tss_ofs, sizeof(TSS));
  57.   asm("movw $0xfe00,%ax");
  58.   asm("int $0x21");
  59.   movedata(edi_seg, edi_ofs, my_ds, (int)(&edi), sizeof(edi));
  60.   movedata(edi.a_tss_seg, edi.a_tss_ofs, my_ds, (int)(&a_tss), sizeof(TSS));
  61.  
  62.   movedata(edi.areas_seg, edi.areas_ofs, my_ds, (int)areas, sizeof(areas));
  63.   for (i=0; i<MAX_AREA; i++)
  64.   {
  65.     areas[i].first_addr -= edi.app_base;
  66.     areas[i].last_addr -= edi.app_base;
  67.   }
  68. }                                         
  69. /* -------------------------------------------------------------- */
  70. void re_start (void)
  71. { int i;
  72.  
  73.   memcpy (&a_tss, &org_tss, sizeof (TSS));
  74.   app_ds = a_tss.tss_ds;
  75.   movedata(edi.areas_seg, edi.areas_ofs, my_ds, (int)areas, sizeof(areas));
  76.   for (i=0; i<MAX_AREA; i++)
  77.   {
  78.     areas[i].first_addr -= edi.app_base;
  79.     areas[i].last_addr -= edi.app_base;
  80.   }
  81. }
  82. /* -------------------------------------------------------------- */
  83. static int invalid_addr(word32 a, unsigned len)
  84. {
  85.   int i;
  86.   if ((int)invalid_addr > 0)
  87.     return 0;
  88.   for (i=0; i<MAX_AREA; i++)
  89.     if (a>=areas[i].first_addr && (a+len-1) <= areas[i].last_addr)
  90.       return 0;
  91.   if (a >= dos_mem_lo && a <= dos_mem_hi)
  92.     return 0;
  93.   printf("Invalid access to child, address %#lx length %#x\n", a, len);
  94.   if (can_longjmp)
  95.     longjmp(debugger_jmpbuf, 1);
  96.   return 1;
  97. }
  98. /* ---------------------------------------------------------------------- */
  99. int
  100. valid_addr (word32 vaddr, int len)
  101. { int a;
  102.  
  103.   if (vaddr >= 0xffffffffl - len)
  104.     return 0;
  105.   len--;
  106.   for (a = 0; a < MAX_AREA; a++)
  107.     if ((vaddr + len <= areas[a].last_addr) && (vaddr >= areas[a].first_addr))
  108.       return 1;
  109.   if (vaddr >= dos_mem_lo && vaddr <= dos_mem_hi)
  110.     return 1;
  111.   return 0;
  112. }
  113. /* -------------------------------------------------------------- */
  114. int read_child(word32 child_addr, void *buf, unsigned len)
  115. {
  116.   if (invalid_addr(child_addr, len))
  117.     return 1;
  118.   if (child_addr >= dos_mem_lo && child_addr <= dos_mem_hi)
  119.     asm ("\n\
  120.       push %ecx\n\
  121.       push %esi\n\
  122.       push %edi\n\
  123.       movl 8(%ebp), %esi\n\
  124.       movl 12(%ebp), %edi\n\
  125.       movl 16(%ebp), %ecx\n\
  126.       cmpl $3, %ecx\n\
  127.       jbe  L_ed_read_ch1\n\
  128.       shrl $2, %ecx\n\
  129.       rep\n\
  130.       movsl\n\
  131.       movl 16(%ebp), %ecx\n\
  132. L_ed_read_ch1:\n\
  133.       andl $3, %ecx\n\
  134.       rep\n\
  135.       movsb\n\
  136.       pop  %edi\n\
  137.       pop  %esi\n\
  138.       pop  %ecx\n\
  139.      ");
  140.   else
  141.     movedata(app_ds, child_addr, my_ds, (int)buf, len);
  142.   return 0;
  143. }
  144. /* -------------------------------------------------------------- */
  145. int write_child(word32 child_addr, void *buf, unsigned len)
  146. {
  147.   if (invalid_addr(child_addr, len))
  148.     return 1;
  149.   if (child_addr >= dos_mem_lo && child_addr <= dos_mem_hi)
  150.     asm ("\n\
  151.       push %ecx\n\
  152.       push %esi\n\
  153.       push %edi\n\
  154.       movl 8(%ebp), %edi\n\
  155.       movl 12(%ebp), %esi\n\
  156.       movl 16(%ebp), %ecx\n\
  157.       cmpl $3, %ecx\n\
  158.       jbe  L_ed_write_ch1\n\
  159.       shrl $2, %ecx\n\
  160.       rep\n\
  161.       movsl\n\
  162.       movl 16(%ebp), %ecx\n\
  163. L_ed_write_ch1:\n\
  164.       andl $3, %ecx\n\
  165.       rep\n\
  166.       movsb\n\
  167.       pop  %edi\n\
  168.       pop  %esi\n\
  169.       pop  %ecx\n\
  170.      ");
  171.   else
  172.     movedata(my_ds, (int)buf, app_ds, child_addr, len);
  173.   return 0;
  174. }
  175. /* -------------------------------------------------------------- */
  176. void ansi(int fg)
  177. {
  178.   if (!edi.ansi_mode)
  179.     return;
  180.   printf("\033[%d;%dm", (fg & A_bold) ? 1 : 0, 30+(fg&7));
  181. }
  182. /* -------------------------------------------------------------- */
  183. static void
  184. setup_env (word32 addr)
  185. { char **envp, test;
  186.   int    env_len, str_len, i;
  187.   word32 env_addr, str_addr;
  188.  
  189.   read_child (addr, &env_addr, 4);
  190.   read_child (env_addr, &str_addr, 4);
  191.   for (env_len = 0; str_addr; env_len++)
  192.     read_child (env_addr + env_len * 4, &str_addr, 4);
  193.   envp = (char **)malloc ((env_len + 1) * sizeof (char *));
  194.   envp[env_len] = 0;
  195.   for (i = 0; i < env_len; i++)
  196.   { read_child (env_addr + i * 4, &str_addr, 4);
  197.     if (str_addr)
  198.     { read_child (str_addr, &test, 1);
  199.       for (str_len = 0; test; str_len++)
  200.     read_child (str_addr + str_len, &test, 1);
  201.       envp[i] = malloc (str_len + 1);
  202.       read_child (str_addr, envp[i], str_len);
  203.       envp[i][str_len] = 0;
  204.     } else
  205.       envp[i] = 0;
  206.   }
  207.   environ = envp;
  208. }
  209. /* -------------------------------------------------------------- */
  210. static void
  211. setup_param (char *fn)
  212. { char *cp;
  213.   int i, len;
  214.  
  215.   old_go32 = 0;
  216.   remote = 0;
  217.   sympath = malloc (258);
  218.   strcpy (sympath, fn);
  219.   symname = strdup (fn);
  220.   symext  = strdup ("sym");
  221.   startup_file = strdup ("/go32/ldbg.rc");
  222.   len = strlen (symname);
  223.   for (i = len - 1; (i > 0) && (i > len - 4) && (symname[i] != '.') &&
  224.             (symname[i] != '\\') && (symname[i] != '/') &&
  225.             (symname[i] != ':'); i--)
  226.     ;
  227.   if (symname[i] != '.')
  228.     i = len;
  229.   symname[i] = 0;
  230.   strcpy (sympath, symname);
  231.   len = strlen (symname);
  232.   for (i = len - 1; (i > 0) && (i > len - 8) && (symname[i] != '\\') &&
  233.             (symname[i] != '/') && (symname[i] != ':'); i--)
  234.     ;
  235.   if (sympath[i] == '/' || sympath[i] == '\\')
  236.     i++;
  237.   strcpy (symname, sympath + i);
  238.   sympath[i] = 0;
  239. /*  cp = 0;
  240.   if (envp)
  241.   { len = 1;
  242.     for (i = 0; envp[i] && len; i++)
  243.     { if (strncmp (envp[i], "LDBG=", 5) == 0)
  244.       { cp = strdup (envp[i] + 5);
  245.     len = 0;
  246.       }                                         
  247.     }
  248.   } */
  249.   cp = getenv ("LDBG");
  250.   if (cp)
  251.   { while (1)
  252.     { char sw[100];
  253.       char val[100];
  254.       if (sscanf(cp, "%s%n", sw, &i) < 1)
  255.     break;
  256.       cp += i;
  257.       if (stricmp(sw, "oldgo32") == 0)
  258.     old_go32 = 1;
  259.       else
  260.       { val[0] = 0;
  261.     sscanf(cp, "%s%n", val, &i);
  262.     cp += i;
  263.     if (val[0] == 0)
  264.       break;
  265.     if (stricmp(sw, "sympath") == 0)
  266.     { strcpy (sympath, val);
  267.     } else if (stricmp(sw, "symname") == 0)
  268.     { if (symname) free(symname);
  269.       symname = strdup(val);
  270.     } else if (stricmp(sw, "symext") == 0)
  271.     { if (symext) free(symext);
  272.       symext = strdup(val);
  273.     } else if (stricmp(sw, "startup") == 0)
  274.     { if (startup_file) free(startup_file);
  275.       startup_file = strdup(val);
  276.     } else if (stricmp(sw, "remote") == 0)
  277.       remote = atol(val);
  278.       }
  279.     }
  280.   }
  281.   i = strlen (sympath);
  282.   if (i > 0)
  283.     if (sympath[i - 1] != '/' && sympath[i - 1] != '\\')
  284.     { sympath[i] = '/';
  285.       sympath[i + 1] = 0;
  286.     }
  287.   if (!old_go32)
  288.     if (edi.com_port)
  289.       remote = edi.com_port;  
  290.   if (remote < 0 || remote > 4)
  291.     remote = 0;
  292. }
  293. /* -------------------------------------------------------------- */
  294. int main (void)
  295. { char *fn;
  296.  
  297.   edi_init ();
  298.   setup_env (a_tss.tss_esp + 0x08);
  299.  
  300.   dos_mem_lo = _go32_info_block.linear_address_of_primary_screen & 0xf0000000;
  301.   dos_mem_hi = dos_mem_lo + 0x0fffffff;
  302.   
  303.   fn = (char *)malloc(edi.filename_len + 1);
  304.   movedata(edi.filename_seg, edi.filename_ofs, my_ds, (int)(fn), edi.filename_len+1);
  305. /*
  306.   printf("text: %#08x - %#08x\n", areas[A_text].first_addr, areas[A_text].last_addr);
  307.   printf("data: %#08x - %#08x\n", areas[A_data].first_addr, areas[A_data].last_addr);
  308.   printf("bss:  %#08x - %#08x\n", areas[A_bss].first_addr, areas[A_bss].last_addr);
  309.   */
  310.  
  311.   setup_param (fn);
  312.   syms_init(fn);
  313.   debugger();
  314.  
  315.   return 0;
  316. }
  317.  
  318. void *sbrk(int l)
  319. {
  320.   extern int end;
  321.   static int sold = (int)&end;
  322.   sold += l;
  323.   return (void *)(sold-l);
  324. }
  325.